package com.jkd.analysis.alarm;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.ejlchina.searcher.BeanSearcher;
import com.ejlchina.searcher.SearchResult;
import com.ejlchina.searcher.operator.Contain;
import com.ejlchina.searcher.operator.Equal;
import com.ejlchina.searcher.util.MapUtils;
import com.jkd.domain.MeasuringPoint;
import com.jkd.domain.Sensor;
import com.jkd.domain.WarningContacts;
import com.jkd.domain.WarningInfo;
import com.jkd.taos.mapper.WarningInfoMapper;
import com.jkd.utils.SendInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Component
@Slf4j
public class MyAlarm {

    @Resource
    private BeanSearcher beanSearcher;

    @Resource
    private WarningInfoMapper warningInfoMapper;

    @Async
    public void judgmentAlarm(String sensorNumber, Double currentValue) {
        Map<String, Object> searcher = MapUtils.builder()
                .field(MeasuringPoint::getSensorCoding, sensorNumber).op(Contain.class).build();
        List<MeasuringPoint> list = beanSearcher.searchAll(MeasuringPoint.class, searcher);
        if (ObjectUtil.isEmpty(list) || list.size() > 1) {
            log.error("存在相同的传感器编号或当前传感器不存在，请注意核实："+sensorNumber);
            return;
        }
        Map<String, Object> searcher1 = MapUtils.builder()
                .field(Sensor::getCoding, sensorNumber).op(Equal.class).build();
        Sensor sensor = beanSearcher.searchFirst(Sensor.class, searcher1);
        if (ObjectUtil.isEmpty(sensor)) {
            log.error("判断报警时找不到该传感器编号设备："+ sensorNumber);
            return;
        }
        MeasuringPoint measuringPoint = list.get(0);
        //阈值报警(需发送短信)
        Boolean f = ObjectUtil.isAllNotEmpty(measuringPoint.getLevel1Warning(), measuringPoint.getLevel2Warning(), measuringPoint.getAlarmValue());
        if (measuringPoint.getAlarmType().contains("1")) {
            if (f) {
                toCheck(measuringPoint, currentValue, sensor);
            } else {
                log.error(measuringPoint.getPointName() + "没有设置完整的报警策略");
            }
        }
        //超量程报警(不发送短信)
        if (measuringPoint.getAlarmType().contains("3")
                && ObjectUtil.isNotEmpty(measuringPoint.getMaximumRange())
                && currentValue > Double.valueOf(measuringPoint.getMaximumRange())) {

            WarningInfo warningInfo = new WarningInfo();
            warningInfo.setContent("测点" + sensor.getInstallPosition() + "监测到数据异常【数据超量程】，时间：" + DateUtil.now() + ",请核实并及时处理。");
            warningInfo.setInstallPoint(sensor.getInstallPosition());
            warningInfo.setSensorCoding(sensor.getCoding());
            warningInfo.setWarningValue(String.valueOf(currentValue));
            warningInfo.setWarningLevel(0);
            warningInfo.setType("3");
            warningInfo.setProjectId(measuringPoint.getProjectId());
            warningInfoMapper.insert(warningInfo);
        }
    }

    public void toCheck(MeasuringPoint measuringPoint, Double monitoringValue, Sensor sensor) {
        Double warningValue1 = Double.valueOf(measuringPoint.getLevel1Warning());
        Double warningValue2 = Double.valueOf(measuringPoint.getLevel2Warning());
        Double bjz = Double.valueOf(measuringPoint.getAlarmValue());
        Integer warningLevel = 0;

        Map<String, Object> searcher = MapUtils.builder()
                .field(WarningContacts::getEnableIs, 0).op(Equal.class)
                .field(WarningContacts::getProjectId, measuringPoint.getProjectId()).op(Equal.class)
                .field(WarningContacts::getPushType, "1").op(Contain.class)
                .build();
        List<WarningContacts> warningContacts = beanSearcher.searchList(WarningContacts.class, searcher);

        if ((monitoringValue >= warningValue1 && monitoringValue < warningValue2) || (monitoringValue <= -warningValue1 && monitoringValue > -warningValue2)) {
            warningLevel = 1;
        } else if ((monitoringValue >= warningValue2 && monitoringValue < bjz) || (monitoringValue <= -warningValue2 && monitoringValue > -bjz)) {
            warningLevel = 2;
        } else if (monitoringValue >= bjz || monitoringValue <= -bjz) {
            warningLevel = 3;
        }

        Integer finalWarningLevel = warningLevel;
        if (finalWarningLevel != 0) {
            WarningInfo warningInfo = new WarningInfo();
            warningInfo.setContent("测点" + sensor.getInstallPosition() + "监测到数据异常【阈值报警】，时间：" + DateUtil.now() + ",请核实并及时处理。");
            warningInfo.setInstallPoint(sensor.getInstallPosition());
            warningInfo.setSensorCoding(sensor.getCoding());
            warningInfo.setWarningValue(String.valueOf(monitoringValue));
            warningInfo.setWarningLevel(warningLevel);
            warningInfo.setType("1");
            warningInfo.setProjectId(measuringPoint.getProjectId());
            warningInfoMapper.insert(warningInfo);
        }
        //如果是3级报警 则发送短信
        if (finalWarningLevel == 3) {
            List<WarningContacts> collect = warningContacts.stream().filter(w -> w.getPushDesc().contains(finalWarningLevel + "#sms")).collect(Collectors.toList());
            if (!collect.isEmpty()) {
                SendInfo.sendSms(collect);
            }
        }
    }
}
